// TestConsole.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"

#include <string>
#include <sstream>
#include <vector>
#include <array>
#include <map>
#include <tuple>
#include <iostream>
#include <algorithm>
#include <cstdarg>
#include <cstdio>
#include <cassert>
#include <atlconv.h>

class CStringHelper
{
public:
	static std::vector<std::string> SplitString(const std::string& str, char delimiter)
	{
		std::vector<std::string> elems;
		std::stringstream ss(str);
		std::string item;
		while (std::getline(ss, item, delimiter))
		{
			elems.push_back(item);
		}
		return elems;
	}

	static std::string ToLower(const std::string& str)
	{
		std::string str2{ str };
		std::transform(str2.begin(), str2.end(), str2.begin(),
			[](decltype(*str.begin())& c) { return ((c >= 'A') && (c <= 'Z')) ? (c - ('Z' - 'z')) : c; }
		);
		return str2;
	}

	static std::string Trim(const std::string& str, const std::string& whitespace = " \t")
	{
		const auto strBegin = str.find_first_not_of(whitespace);
		if (strBegin == std::string::npos)
			return ""; // no content

		const auto strEnd = str.find_last_not_of(whitespace);
		const auto strRange = strEnd - strBegin + 1;
		return str.substr(strBegin, strRange);
	}
};

void PrintFormatedString(const char* format, ...)
{
	const int BUFFER_SIZE = 256;
	char buffer[BUFFER_SIZE];
	va_list args;
	va_start(args, format);
	vsprintf_s(buffer, BUFFER_SIZE, format, args);
	va_end(args);

	std::cout << buffer << std::endl;
}

enum class GroupType
{
	Node = 1,
	Element = 2
};

int _tmain(int argc, _TCHAR* argv[])
{
	std::string str{"  \t BlaBLa\n\tahAh\nxXXx *** \t \" \'  "};
	auto tokens = CStringHelper::SplitString(str, '\n');
	for (auto&& token : tokens)
	{
		std::cout << token << std::endl;
	}
		
	std::cout << str << std::endl;
	std::cout << "ToLower" << CStringHelper::ToLower(str) << std::endl;
	std::cout << "Trim:" << CStringHelper::Trim(str, " \t\"\'") << std::endl;

	int nodeCount = 12;
	std::array<int, 3> base{ nodeCount, nodeCount * 2, nodeCount * 3 };

	std::map<int, std::tuple<double, double, double>> m_NodeData;
	int nodeNum = 123;
	double x = 1.2, y = 3.4, z = 5.6;
	m_NodeData.insert(std::make_pair(nodeNum, std::make_tuple(x, y, z)));

	int i = 123;
	double d = 345.67;
	char* str5 = "str5";
	PrintFormatedString("PrintFormatedString: i=%d, d=%f, str5=%s", i, d, str5);

	std::vector<int> vi{ 3,6,1,8,12,9 };
	
	std::vector<int> vi2{ vi.begin(), std::remove_if(vi.begin(), vi.end(), [](int i) { return  (i % 2) == 0; }) };
	for (auto&& i : vi2)
	{
		std::cout << i << std::endl;
	}

	std::vector<int> vi3(3);
	vi3[0] = 12;
	vi3[1] = 54;
	vi3.push_back(67);

	std::vector<int> vi4{ 3 };

	int gt = 2;
	auto groupType = static_cast<GroupType>(gt);
	assert(groupType == GroupType::Element);

	USES_CONVERSION;
	char* str6 = "~Hello, world!";
	std::wstring str7{ CA2W(str6, CP_UTF8) };

	std::wstring str8(3, ',');

	//std::getchar();
	return 0;
}

